package com.onlocation.gui;

import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.os.Bundle;
import android.text.InputType;
import android.view.View;
import android.view.WindowManager;
import android.widget.*;
import com.onlocation.db.DatabaseHelper;
import com.onlocation.objects.Location;
import com.onlocation.objects.OkCancelDialog;
import com.onlocation.R;
import com.onlocation.util.CoordinateUtil;
import com.onlocation.util.PreferenceUtil;
import com.onlocation.util.ResourceUtil;
import com.onlocation.util.StringUtil;
import com.onlocation.util.VolumeUtil;

import java.util.ArrayList;

/**
 * Author: Steve Carrell
 * Date: 5/10/12
 */
public class EditLocation extends Activity {
    public static final int EDIT_LOCATION_REQUEST_CD = 1;
    public static final int EDIT_LOCATION_RESULT_CD = 1;

    private boolean allowNameEdit = false;
    private boolean isNewLocation = false;
    private int position = -1;
    private ArrayList<String> locations = new ArrayList<String>();
    private final DatabaseHelper db = DatabaseHelper.getInstance(this);
    private Location location;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.edit_location);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

        allowNameEdit = getIntent().getExtras().getBoolean("allowNameEdit");
        isNewLocation = getIntent().getExtras().getBoolean("isNewLocation");
        position = getIntent().getExtras().getInt("position");
        locations = getIntent().getExtras().getStringArrayList("locations");

        setData();
    }
    
    public void setData() {
        if (!isNewLocation) {
            location = db.getLocationData(locations.get(position));
        } else {
            location = new Location();
        }
        updateNameField(location.getName());
        updateLongitudeField(location.getLongitude());
        updateLatitudeField(location.getLatitude());
        updateRadiusField(location.getRadius());
        updateVolumeBar(location.getVolume());
        updateVibrateCb(location.getVibrate());
        updateButtonsEnabled();
        updatePanelLayoutAndEntry();
    }

    @Override
    public void onBackPressed() {
        // verify name is valid, if not ask if user wants to discard changes
        String name = ((EditText) findViewById(R.id.nameTxt)).getText().toString();
        Double longitude = Double.valueOf(((EditText) findViewById(R.id.longTxt)).getText().toString());
        Double latitude = Double.valueOf(((EditText) findViewById(R.id.latTxt)).getText().toString());
        Float radius = Location.radiusToMeters(
                Float.valueOf(((EditText) findViewById(R.id.radiusTxt)).getText().toString()));
        Integer volume = ((SeekBar) findViewById(R.id.volumeBar)).getProgress();
        Boolean vibrate = ((CheckBox) findViewById(R.id.vibrateCb)).isChecked();

        if (StringUtil.isNullOrEmpty(name)) {
            exitAction(false);
        } else if ((isNewLocation && locations.contains(name)) ||
                (!isNewLocation && locations.indexOf(name) != position && locations.indexOf(name) >= 0)) {
            // invalid name
            OkCancelDialog dlg = new OkCancelDialog(this, "", ResourceUtil.getString(R.string.errorInvalidName)) {
                protected void okAction() {
                    exitAction(false);
                }
                protected void cancelAction() {
                    // set focus on name
                    EditText nameTxt = (EditText) findViewById(R.id.nameTxt);
                    nameTxt.requestFocus();
                }
            };
            dlg.show();
        } else if (!isNewLocation) {
            Location newLocation = new Location();
            newLocation.setName(name);
            newLocation.setLongitude(longitude);
            newLocation.setLatitude(latitude);
            newLocation.setRadius(radius);
            newLocation.setVolume(volume);
            newLocation.setVibrate(vibrate);
            if (!location.equals(newLocation)) {
                // update location
                db.updateLocation(locations.get(position), newLocation);
                exitAction(true);
            } else {
                exitAction(false);
            }
        } else {
            // add location
            db.addNewLocation(name, longitude, latitude, radius, volume, vibrate);
            exitAction(true);
        }
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    }

    public void onClick_coordBtn(View view) {
        Button coordBtn = (Button) view;
        coordBtn.setEnabled(false);
        EditText longTxt = (EditText) findViewById(R.id.longTxt);
        EditText latTxt = (EditText) findViewById(R.id.latTxt);
        EditText radiusTxt = (EditText) findViewById(R.id.radiusTxt);
        longTxt.setText(CoordinateUtil.getCurrentLongitude().toString());
        latTxt.setText(CoordinateUtil.getCurrentLatitude().toString());
        radiusTxt.setText(CoordinateUtil.getCurrentAccuracy().toString());
        coordBtn.setEnabled(true);
    }
    
    public void onClick_mapBtn(View view) {
        Bundle send = new Bundle();
        send.putFloat("longitude",
                Float.valueOf(((EditText) findViewById(R.id.longTxt)).getText().toString()));
        send.putFloat("latitude",
                Float.valueOf(((EditText) findViewById(R.id.latTxt)).getText().toString()));
        Intent intent = new Intent(this, LocateMap.class);
        intent.putExtras(send);
        startActivityForResult(intent, LocateMap.LOCATE_MAP_REQUEST_CD);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // update long/lat
        if (requestCode == LocateMap.LOCATE_MAP_REQUEST_CD &&
                resultCode == LocateMap.LOCATE_MAP_RESULT_CD) {
            updateLongitudeField(data.getExtras().getDouble("longitude"));
            updateLatitudeField(data.getExtras().getDouble("latitude"));
        }
    }

    private void exitAction(boolean refreshLocations) {
        Intent intent = new Intent();
        intent.putExtra("refreshLocations", refreshLocations);
        setResult(EDIT_LOCATION_RESULT_CD, intent);
        super.onBackPressed();
    }

    private void updateNameField(String name) {
        EditText nameTxt = (EditText) findViewById(R.id.nameTxt);
        nameTxt.setEnabled(allowNameEdit);
        if (!isNewLocation) {
            nameTxt.setText(name);
        }
    }

    private void updateLongitudeField(Double longitude) {
        EditText longTxt = (EditText) findViewById(R.id.longTxt);
        longTxt.setEnabled(allowNameEdit);
        if (isNewLocation && longitude == 0.0) {
            longTxt.setText(CoordinateUtil.getCurrentLongitude().toString());
        } else {
            longTxt.setText(longitude.toString());
        }
    }

    private void updateLatitudeField(Double latitude) {
        EditText latTxt = (EditText) findViewById(R.id.latTxt);
        latTxt.setEnabled(allowNameEdit);
        if (isNewLocation && latitude == 0.0) {
            latTxt.setText(CoordinateUtil.getCurrentLatitude().toString());
        } else {
            latTxt.setText(latitude.toString());
        }
    }

    private void updateRadiusField(Float radius) {
        TextView radiusSubLbl = (TextView) findViewById(R.id.radiusSubLbl);
        EditText radiusTxt = (EditText) findViewById(R.id.radiusTxt);
        radiusSubLbl.setText(
                String.format(ResourceUtil.getString(R.string.radiusSubLbl),
                PreferenceUtil.getRadiusUnits()));
        radiusTxt.setEnabled(allowNameEdit);
        if (isNewLocation && radius == 0.0f) {
            radiusTxt.setText(Location.radiusToPrefMeas(
                    CoordinateUtil.getCurrentAccuracy()).toString());
        } else {
            radiusTxt.setText(Location.radiusToPrefMeas(radius).toString());
        }
    }
    
    private void updateVolumeBar(Integer volume) {
        SeekBar volumeBar = (SeekBar) findViewById(R.id.volumeBar);
        if (isNewLocation) {
            volumeBar.setProgress(VolumeUtil.getCurrentVolume());
        } else {
            volumeBar.setProgress(volume);
        }
    }
    
    private void updateVibrateCb(Boolean vibrate) {
        CheckBox vibrateCb = (CheckBox) findViewById(R.id.vibrateCb);
        if (isNewLocation) {
            vibrateCb.setChecked(VolumeUtil.getCurrentIsVibrate());
        } else {
            vibrateCb.setChecked(vibrate);
        }
    }

    private void updateButtonsEnabled() {
        Button coordBtn = (Button) findViewById(R.id.coordBtn);
        coordBtn.setEnabled(allowNameEdit);
        Button mapBtn = (Button) findViewById(R.id.mapBtn);
//        mapBtn.setEnabled(allowNameEdit);
        mapBtn.setEnabled(false);
    }

    private void updatePanelLayoutAndEntry() {
        if (!allowNameEdit) {
            // Disable soft keyboard on nameTxt (input already disabled) and hide the coord panel.
            EditText nameTxt = (EditText) findViewById(R.id.nameTxt);
            TableLayout coordPanel = (TableLayout) findViewById(R.id.coordPanel);
            nameTxt.setInputType(InputType.TYPE_NULL);
            coordPanel.setVisibility(View.GONE);
        } else if (!isNewLocation) {
            // We already have a name set for the selected location.
            // Hide the keyboard unless user explicitly opens text for edit.
            getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
        }
    }
}
